from pydantic import BaseModel, Field
from typing import Optional, List
from datetime import datetime
from enum import Enum


class ContractPeriod(str, Enum):
    TEN_MINUTES = "10m"
    THIRTY_MINUTES = "30m"
    ONE_HOUR = "1h"
    ONE_DAY = "1d"


class PredictionDirection(str, Enum):
    UP = "up"
    DOWN = "down"


class ContractStatus(str, Enum):
    ACTIVE = "active"
    SETTLED = "settled"
    UNKNOWN = "unknown"


class BalanceLogType(str, Enum):
    BET = "bet"
    PROFIT = "profit"
    LOSS = "loss"
    REFUND = "refund"


# User Schemas
class UserCreate(BaseModel):
    username: str = Field(..., min_length=1, max_length=50)


class UserResponse(BaseModel):
    id: str
    username: str
    balance: float
    created_at: datetime
    
    class Config:
        orm_mode = True


# Contract Schemas
class ContractCreate(BaseModel):
    user_id: str
    symbol: str = Field(..., regex="^(ETHUSDT|BTCUSDT)$")
    period: ContractPeriod
    direction: PredictionDirection
    bet_amount: float = Field(..., gt=0)


class ContractResponse(BaseModel):
    id: str
    user_id: str
    symbol: str
    period: str
    direction: str
    bet_amount: float
    anchor_price: float
    anchor_timestamp: int
    expiry_timestamp: int
    final_price: Optional[float] = None
    profit: Optional[float] = None
    status: str
    created_at: datetime
    
    class Config:
        orm_mode = True


# Price Schemas
class PriceData(BaseModel):
    symbol: str
    price: float
    timestamp: int


class PriceResponse(BaseModel):
    symbol: str
    price: float
    timestamp: int
    created_at: datetime
    
    class Config:
        orm_mode = True


# Balance Log Schemas
class BalanceLogResponse(BaseModel):
    id: str
    user_id: str
    contract_id: Optional[str] = None
    amount: float
    balance_before: float
    balance_after: float
    type: str
    created_at: datetime
    
    class Config:
        orm_mode = True


# WebSocket Messages
class WSMessage(BaseModel):
    type: str
    data: dict


class PriceUpdateMessage(BaseModel):
    type: str = "price_update"
    symbol: str
    price: float
    timestamp: int


class ContractUpdateMessage(BaseModel):
    type: str = "contract_update"
    contract: ContractResponse


class BalanceUpdateMessage(BaseModel):
    type: str = "balance_update"
    user_id: str
    balance: float
